package MeshlessShapeFunctions;

import java.util.ArrayList;
import java.util.Iterator;

import jmeshless.NewOkCancelDialog;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import HashMatrix2.HashMatrix2;
import HashMatrix2.LUFactorization;
import MathLib.HashMatrix.Gauss;
import MathLib.HashMatrix.HashMatrix;

public class stTMP {
	public static double w(double y, double x, double ro){
		double locw = 0.0;
		if (Math.abs(y-x)<ro){
			locw =Math.sqrt(4/Math.PI)*Math.pow( (1- Math.pow( (Math.abs(y-x))/(ro), 2) ), 4);
		}
		else {
			locw=0;
		}
		return locw;
	}
	
	public static double wpoh(double y, double x, double ro){
		double locw = 0.0;
		if (Math.abs(y-x)<ro){
			locw =Math.sqrt(4/Math.PI)*Math.pow( (1- Math.pow( (Math.abs(y-x))/(ro), 2) ), 3)*(-2)*(y-x) / (ro) / ro/ ro/ ro;
		}
		else {
			locw=0;
		}
		return locw;
	}
	
	public static double phi(double ro, double a, double b, double y, int n, int rozmir, int i, double[] xvuz){
		double[] wd = new double[xvuz.length];
		double[] wd2 = new double[xvuz.length];
		for (int j = 0; j < xvuz.length; j++) {
			wd[j] = w(y, xvuz[j], ro);
			wd2[j] = wpoh(y, xvuz[j], ro);
		}
		double[][] p = new double[3][n];
		for (int k = 0; k < p[0].length; k++) {
				p[0][k]=1;
			    p[1][k]=xvuz[k];
			    p[2][k]=xvuz[k]*xvuz[k];
		}
		
		HashMatrix amatr = new HashMatrix(HashMatrix.ARRAY_TYPE, rozmir+1);
		HashMatrix a2matr = new HashMatrix(HashMatrix.ARRAY_TYPE, rozmir+1);
		for (int k = 0; k <= rozmir; k++) {
			for (int l = 0; l <= rozmir; l++) {
				double tmp = 0.0;
				for (int m = 0; m < n; m++) {
					tmp+=p[k][m]*p[l][m]*wd[m];
				}
//				System.out.print(tmp+"\t\t");
				amatr.setValue(k, l, tmp);
				a2matr.setValue(k, l, tmp);
			}
//			System.out.print("\n");
		}
		
		
		double[] bvect = new double[rozmir+1];
		boolean key = false;
		for (int j = 0; j < bvect.length; j++) {
			bvect[j] = wd[i]*p[j][i];
			if(Math.abs(bvect[j])>0.0000001){
				key= true;
			}
		}
		double[] x = null;
		if (key) {
			Gauss g = new Gauss(amatr);
			x = g.calculate(bvect);
//			switch (rozmir) {
//			case 1:
//				return x[0]+y*x[1];
//			case 2:
//				return x[0]+y*x[1]+y*y*x[2];
//			case 3:
//				return x[0]+y*x[1]+y*y*x[2]+y*y*y*x[3];
//			default:
//				break;
//			}
		}else{return 0.0;}
		
		
		key = false;
		for (int j = 0; j < bvect.length; j++) {
			bvect[j] = wd2[i]*p[j][i];
		}
		
		for (int j = 0; j < bvect.length; j++) {
			//-p[k,m]*p[l,m]*wd2[m]*x[l];
			double tmp = 0.0;
			for (int l = 0; l <=rozmir; l++) {
				for (int m = 0; m < n; m++) {
					tmp+=p[j][m]*p[l][m]*wd2[m]*x[l];
				}				
			}
			bvect[j] -= tmp;
			if(Math.abs(bvect[j])>0.0000001){
				key= true;
			}
		}
		
		if (key) {
			Gauss g = new Gauss(a2matr);
			double[] xpoh = g.calculate(bvect);
			switch (rozmir) {
			case 1:
				return xpoh[0]+x[1]+y*xpoh[1];
			case 2:
				return xpoh[0]+x[1]+y*xpoh[1]+2*y*x[2]+y*y*xpoh[2];
			case 3:
				return xpoh[0]+x[1]+y*xpoh[1]+2*y*x[2]+y*y*xpoh[2]+3*y*y*x[3]+y*y*y*xpoh[3];
			default:
				break;
			}
		}
		
		
		
		return 0.0;
		
		
		
		
	}
	
	public static void main(String[] args){
		double a = 0.0,b=1;
//      int nn = 10;
//      double[] xvuz = new double[nn+1];
//      double h = (b-a)/(double)nn;
//      for (int i = 0; i <=nn; i++) {
//          xvuz[i] = (a+h*i);
//      }
		
		ArrayList<Particle> NodeList = new ArrayList<Particle>();
		NodeList.add( new Particle(0.0 , 0,0 ));
		NodeList.add( new Particle(0.1 , 0,1 ));
		NodeList.add( new Particle(0.15000000000000002 , 0,3 ));
		NodeList.add( new Particle(0.2 , 0,5 ));
		NodeList.add( new Particle(0.25 , 0,7 ));
		NodeList.add( new Particle(0.30000000000000004 , 0,9 ));
		NodeList.add( new Particle(0.35000000000000003 , 0,11 ));
		NodeList.add( new Particle(0.4 , 0,13 ));
		NodeList.add( new Particle(0.45 , 0,15 ));
		NodeList.add( new Particle(0.5 , 0,17 ));
		NodeList.add( new Particle(0.55 , 0,19 ));
		NodeList.add( new Particle(0.6000000000000001 , 0,21 ));
		NodeList.add( new Particle(0.6250000000000001 , 0,22 ));
		NodeList.add( new Particle(0.6500000000000001 , 0,23 ));
		NodeList.add( new Particle(0.675 , 0,24 ));
		NodeList.add( new Particle(0.7000000000000001 , 0,25 ));
		NodeList.add( new Particle(0.7250000000000001 , 0,26 ));
		NodeList.add( new Particle(0.75 , 0,27 ));
		NodeList.add( new Particle(0.775 , 0,28 ));
		NodeList.add( new Particle(0.8 , 0,29 ));
		NodeList.add( new Particle(0.8250000000000001 , 0,30 ));
		NodeList.add( new Particle(0.8500000000000001 , 0,31 ));
		NodeList.add( new Particle(0.875 , 0,32 ));
		NodeList.add( new Particle(0.9 , 0,33 ));
		NodeList.add( new Particle(0.95 , 0,34 ));
		NodeList.add( new Particle(1.0 , 0,35 ));
		
		double xz = 0.0;
        for (int i = 1; i < NodeList.size()-1; i++) {
        	xz = Math.max(xz,NodeList.get(i).getX()-NodeList.get(i-1).getX());
        }
        	double tmpRho = 2.33*Math.max(0, NodeList.get(1).getX()-NodeList.get(0).getX());
        tmpRho = 2.33*xz;
		
		ArrayList<JMeshlessInterpolationFunction1D> FuncList = new ArrayList<JMeshlessInterpolationFunction1D>();
//        	System.out.println(tmpRho);
    		JMeshlessInterpolationFunction1D tmp = new JMeshlessInterpolationFunction1D(1,NodeList.get(0).getX(),tmpRho,new JGaussian(tmpRho) ); 
    		tmp.setNodeList(NodeList);
        	FuncList.add(tmp );
        for (int i = 1; i < NodeList.size()-1; i++) {
//        	tmpRho = 2.33*Math.max(NodeList.get(i).getX()-NodeList.get(i-1).getX(), NodeList.get(i+1).getX()-NodeList.get(i).getX());
        	tmp = new JMeshlessInterpolationFunction1D(1,NodeList.get(i).getX(),tmpRho,new JGaussian(tmpRho) ); 
        	tmp.setNodeList(NodeList);
            FuncList.add(tmp );
//            System.out.println(tmpRho);
        }
        tmpRho = 2.33*Math.max(0, NodeList.get(NodeList.size()-1).getX()-NodeList.get(NodeList.size()-2).getX());
		tmp = new JMeshlessInterpolationFunction1D(1,NodeList.get(NodeList.size()-1).getX(),tmpRho,new JGaussian(tmpRho) ); 
		tmp.setNodeList(NodeList);
		FuncList.add(tmp );
		for (Iterator<JMeshlessInterpolationFunction1D> iterator = FuncList.iterator(); iterator.hasNext();) {
			JMeshlessInterpolationFunction1D jMeshlessInterpolationFunction1D = iterator.next();
			jMeshlessInterpolationFunction1D.setNodeList(NodeList);
		}
		
		HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, NodeList.size());
		double[] B = new double[NodeList.size()];
		for (int i = 0; i < A.getN(); i++) {
			double x = NodeList.get(i).getX();
			for (int j = 0; j < A.getN(); j++) {
				A.setValue(i, j, FuncList.get(j).calculate(x));
			}
			B[i] = Math.sin(6*x);
		}
		
		LUFactorization lu = new LUFactorization(A);
		double[] res = lu.calculate(B); 
      
      double x=a;
//      x = 0.5;
//      System.out.println(x+"\t\t"+(phi(0.5, a, b, x, nn+1, 2, 5, xvuz)));
      XYSeries series1 = new XYSeries("Function", true, true);
      while(x<=1.0001){
          double tmp1 = 0.0;
          for (int j = 0; j <res.length; j++) {
              tmp1+= FuncList.get(j).calculate(x)*res[j];
          }
          series1.add(x,tmp1);
          x+=0.0001;
      }
      XYSeriesCollection col  = new XYSeriesCollection(series1);
      NewOkCancelDialog dialog = new NewOkCancelDialog(null, false, col);
      dialog.setLocationRelativeTo(null);
      dialog.setVisible(true);
      
      
      
      
      XYSeriesCollection col1 = new XYSeriesCollection();
      for (Iterator<JMeshlessInterpolationFunction1D> it = FuncList.iterator(); it.hasNext();) {
			JMeshlessInterpolationFunction1D jm = (JMeshlessInterpolationFunction1D) it.next();
			x = 0.0;
			 	XYSeries series = new XYSeries("", true, true);
  	        while(x<=1.0001){
  	            double tmp1 = jm.calculate(x);
  	            series.add(x,tmp1);
  	            x+=0.002;
  	        }
  	        col1.addSeries(series);
		}
      NewOkCancelDialog dialog1 = new NewOkCancelDialog(null, false, col1);
      dialog1.setLocationRelativeTo(null);
      dialog1.setVisible(true);
      
      
      
	}
}
